home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 2 / AACD 2.iso / AACD / Magazine / GraphicsCards / StormMesa / src / teximage.c < prev    next >
C/C++ Source or Header  |  1999-02-04  |  70KB  |  2,413 lines

  1. /* $Id: teximage.c,v 3.11 1998/07/18 03:35:01 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.0
  6.  * Copyright (C) 1995-1998  Brian Paul
  7.  *
  8.  * This library is free software; you can redistribute it and/or
  9.  * modify it under the terms of the GNU Library General Public
  10.  * License as published by the Free Software Foundation; either
  11.  * version 2 of the License, or (at your option) any later version.
  12.  *
  13.  * This library is distributed in the hope that it will be useful,
  14.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.  * Library General Public License for more details.
  17.  *
  18.  * You should have received a copy of the GNU Library General Public
  19.  * License along with this library; if not, write to the Free
  20.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  */
  22.  
  23.  
  24. /*
  25.  * $Log: teximage.c,v $
  26.  * Revision 3.11  1998/07/18 03:35:01  brianp
  27.  * fixed a few error reporting mistakes
  28.  *
  29.  * Revision 3.10  1998/07/17 03:25:17  brianp
  30.  * implemented glGetTexImage()
  31.  *
  32.  * Revision 3.9  1998/05/05 00:28:52  brianp
  33.  * GL_ABGR_EXT pixel format now works with glTexImageXD()
  34.  *
  35.  * Revision 3.8  1998/05/05 00:19:47  brianp
  36.  * added GL_COLOR_INDEX to cases in components_in_intformat
  37.  *
  38.  * Revision 3.7  1998/04/20 21:46:08  brianp
  39.  * added David's second glCopyTexSubImage() patch
  40.  *
  41.  * Revision 3.6  1998/04/13 23:16:57  brianp
  42.  * fixed 3Dfx glCopyTexSubImage() bug (David Bucciarelli)
  43.  *
  44.  * Revision 3.5  1998/03/27 04:17:31  brianp
  45.  * fixed G++ warnings
  46.  *
  47.  * Revision 3.4  1998/03/03 02:42:38  brianp
  48.  * removed a few unneeded assertions
  49.  *
  50.  * Revision 3.3  1998/02/20 04:53:37  brianp
  51.  * implemented GL_SGIS_multitexture
  52.  *
  53.  * Revision 3.2  1998/02/07 14:42:29  brianp
  54.  * NULL proxy image given to glTexImageXD() caused crash (Wes Bethel)
  55.  *
  56.  * Revision 3.1  1998/02/01 22:28:41  brianp
  57.  * removed an unneeded header
  58.  *
  59.  * Revision 3.0  1998/01/31 21:04:38  brianp
  60.  * initial rev
  61.  *
  62.  */
  63.  
  64.  
  65. #ifdef PC_HEADER
  66. #include "all.h"
  67. #else
  68. #include <assert.h>
  69. #include <stdio.h>
  70. #include <stdlib.h>
  71. #include <string.h>
  72. #include "context.h"
  73. #include "image.h"
  74. #include "macros.h"
  75. #include "span.h"
  76. #include "teximage.h"
  77. #include "types.h"
  78. #endif
  79.  
  80.  
  81. /*
  82.  * NOTES:
  83.  *
  84.  * The internal texture storage convension is an array of N GLubytes
  85.  * where N = width * height * components.  There is no padding.
  86.  */
  87.  
  88.  
  89.  
  90.  
  91. /*
  92.  * Compute log base 2 of n.
  93.  * If n isn't an exact power of two return -1.
  94.  * If n<0 return -1.
  95.  */
  96. static int logbase2( int n )
  97. {
  98.    GLint i = 1;
  99.    GLint log2 = 0;
  100.  
  101.    if (n<0) {
  102.       return -1;
  103.    }
  104.  
  105.    while ( n > i ) {
  106.       i *= 2;
  107.       log2++;
  108.    }
  109.    if (i != n) {
  110.       return -1;
  111.    }
  112.    else {
  113.       return log2;
  114.    }
  115. }
  116.  
  117.  
  118.  
  119. /*
  120.  * Given an internal texture format enum or 1, 2, 3, 4 return the
  121.  * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
  122.  * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return -1 if
  123.  * invalid enum.
  124.  */
  125. static GLint decode_internal_format( GLint format )
  126. {
  127.    switch (format) {
  128.       case GL_ALPHA:
  129.       case GL_ALPHA4:
  130.       case GL_ALPHA8:
  131.       case GL_ALPHA12:
  132.       case GL_ALPHA16:
  133.      return GL_ALPHA;
  134.       case 1:
  135.       case GL_LUMINANCE:
  136.       case GL_LUMINANCE4:
  137.       case GL_LUMINANCE8:
  138.       case GL_LUMINANCE12:
  139.       case GL_LUMINANCE16:
  140.      return GL_LUMINANCE;
  141.       case 2:
  142.       case GL_LUMINANCE_ALPHA:
  143.       case GL_LUMINANCE4_ALPHA4:
  144.       case GL_LUMINANCE6_ALPHA2:
  145.       case GL_LUMINANCE8_ALPHA8:
  146.       case GL_LUMINANCE12_ALPHA4:
  147.       case GL_LUMINANCE12_ALPHA12:
  148.       case GL_LUMINANCE16_ALPHA16:
  149.      return GL_LUMINANCE_ALPHA;
  150.       case GL_INTENSITY:
  151.       case GL_INTENSITY4:
  152.       case GL_INTENSITY8:
  153.       case GL_INTENSITY12:
  154.       case GL_INTENSITY16:
  155.      return GL_INTENSITY;
  156.       case 3:
  157.       case GL_RGB:
  158.       case GL_R3_G3_B2:
  159.       case GL_RGB4:
  160.       case GL_RGB5:
  161.       case GL_RGB8:
  162.       case GL_RGB10:
  163.       case GL_RGB12:
  164.       case GL_RGB16:
  165.      return GL_RGB;
  166.       case 4:
  167.       case GL_RGBA:
  168.       case GL_RGBA2:
  169.       case GL_RGBA4:
  170.       case GL_RGB5_A1:
  171.       case GL_RGBA8:
  172.       case GL_RGB10_A2:
  173.       case GL_RGBA12:
  174.       case GL_RGBA16:
  175.      return GL_RGBA;
  176.       case GL_COLOR_INDEX1_EXT:
  177.       case GL_COLOR_INDEX2_EXT:
  178.       case GL_COLOR_INDEX4_EXT:
  179.       case GL_COLOR_INDEX8_EXT:
  180.       case GL_COLOR_INDEX12_EXT:
  181.       case GL_COLOR_INDEX16_EXT:
  182.      return GL_COLOR_INDEX;
  183.       default:
  184.      return -1;  /* error */
  185.    }
  186. }
  187.  
  188.  
  189.  
  190. /*
  191.  * Given an internal texture format enum or 1, 2, 3, 4 return the
  192.  * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
  193.  * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.  Return the
  194.  * number of components for the format.  Return -1 if invalid enum.
  195.  */
  196. static GLint components_in_intformat( GLint format )
  197. {
  198.    switch (format) {
  199.       case GL_ALPHA:
  200.       case GL_ALPHA4:
  201.       case GL_ALPHA8:
  202.       case GL_ALPHA12:
  203.       case GL_ALPHA16:
  204.      return 1;
  205.       case 1:
  206.       case GL_LUMINANCE:
  207.       case GL_LUMINANCE4:
  208.       case GL_LUMINANCE8:
  209.       case GL_LUMINANCE12:
  210.       case GL_LUMINANCE16:
  211.      return 1;
  212.       case 2:
  213.       case GL_LUMINANCE_ALPHA:
  214.       case GL_LUMINANCE4_ALPHA4:
  215.       case GL_LUMINANCE6_ALPHA2:
  216.       case GL_LUMINANCE8_ALPHA8:
  217.       case GL_LUMINANCE12_ALPHA4:
  218.       case GL_LUMINANCE12_ALPHA12:
  219.       case GL_LUMINANCE16_ALPHA16:
  220.      return 2;
  221.       case GL_INTENSITY:
  222.       case GL_INTENSITY4:
  223.       case GL_INTENSITY8:
  224.       case GL_INTENSITY12:
  225.       case GL_INTENSITY16:
  226.      return 1;
  227.       case 3:
  228.       case GL_RGB:
  229.       case GL_R3_G3_B2:
  230.       case GL_RGB4:
  231.       case GL_RGB5:
  232.       case GL_RGB8:
  233.       case GL_RGB10:
  234.       case GL_RGB12:
  235.       case GL_RGB16:
  236.      return 3;
  237.       case 4:
  238.       case GL_RGBA:
  239.       case GL_RGBA2:
  240.       case GL_RGBA4:
  241.       case GL_RGB5_A1:
  242.       case GL_RGBA8:
  243.       case GL_RGB10_A2:
  244.       case GL_RGBA12:
  245.       case GL_RGBA16:
  246.      return 4;
  247.       case GL_COLOR_INDEX:
  248.       case GL_COLOR_INDEX1_EXT:
  249.       case GL_COLOR_INDEX2_EXT:
  250.       case GL_COLOR_INDEX4_EXT:
  251.       case GL_COLOR_INDEX8_EXT:
  252.       case GL_COLOR_INDEX12_EXT:
  253.       case GL_COLOR_INDEX16_EXT:
  254.      return 1;
  255.       default:
  256.      return -1;  /* error */
  257.    }
  258. }
  259.  
  260.  
  261.  
  262. struct gl_texture_image *gl_alloc_texture_image( void )
  263. {
  264.    return (struct gl_texture_image *) calloc( 1, sizeof(struct gl_texture_image) );
  265. }
  266.  
  267.  
  268.  
  269. void gl_free_texture_image( struct gl_texture_image *teximage )
  270. {
  271.    if (teximage->Data) {
  272.       free( teximage->Data );
  273.    }
  274.    free( teximage );
  275. }
  276.  
  277.  
  278.  
  279. /*
  280.  * Given a gl_image, apply the pixel transfer scale, bias, and mapping
  281.  * to produce a gl_texture_image.  Convert image data to GLubytes.
  282.  * Input:  image - the incoming gl_image
  283.  *         internalFormat - desired format of resultant texture
  284.  *         border - texture border width (0 or 1)
  285.  * Return:  pointer to a gl_texture_image or NULL if an error occurs.
  286.  */
  287. static struct gl_texture_image *
  288. image_to_texture( GLcontext *ctx, const struct gl_image *image,
  289.           GLint internalFormat, GLint border )
  290. {
  291.    GLint components;
  292.    struct gl_texture_image *texImage;
  293.    GLint numPixels, pixel;
  294.    GLboolean scaleOrBias;
  295.  
  296.    assert(image);
  297.    assert(image->Width>0);
  298.    assert(image->Height>0);
  299.    assert(image->Depth>0);
  300.  
  301.    /*   internalFormat = decode_internal_format(internalFormat);*/
  302.    components = components_in_intformat(internalFormat);
  303.    numPixels = image->Width * image->Height * image->Depth;
  304.  
  305.    texImage = gl_alloc_texture_image();
  306.    if (!texImage)
  307.       return NULL;
  308.  
  309.    texImage->Format = (GLenum) decode_internal_format(internalFormat);
  310.    texImage->IntFormat = (GLenum) internalFormat;
  311.    texImage->Border = border;
  312.    texImage->Width = image->Width;
  313.    texImage->Height = image->Height;
  314.    texImage->Depth = image->Depth;
  315.    texImage->WidthLog2 = logbase2(image->Width - 2*border);
  316.    if (image->Height==1)  /* 1-D texture */
  317.       texImage->HeightLog2 = 0;
  318.    else
  319.       texImage->HeightLog2 = logbase2(image->Height - 2*border);
  320.    if (image->Depth==1)   /* 2-D texture */
  321.       texImage->DepthLog2 = 0;
  322.    else
  323.       texImage->DepthLog2 = logbase2(image->Depth - 2*border);
  324.    texImage->Width2 = 1 << texImage->WidthLog2;
  325.    texImage->Height2 = 1 << texImage->HeightLog2;
  326.    texImage->Depth2 = 1 << texImage->DepthLog2;
  327.    texImage->MaxLog2 = MAX2( texImage->WidthLog2, texImage->HeightLog2 );
  328.    texImage->Data = (GLubyte *) malloc( numPixels * components );
  329.  
  330.    if (!texImage->Data) {
  331.       /* out of memory */
  332.       gl_free_texture_image( texImage );
  333.       return NULL;
  334.    }
  335.  
  336.    /* Determine if scaling and/or biasing is needed */
  337.    if (ctx->Pixel.RedScale!=1.0F   || ctx->Pixel.RedBias!=0.0F ||
  338.        ctx->Pixel.GreenScale!=1.0F || ctx->Pixel.GreenBias!=0.0F ||
  339.        ctx->Pixel.BlueScale!=1.0F  || ctx->Pixel.BlueBias!=0.0F ||
  340.        ctx->Pixel.AlphaScale!=1.0F || ctx->Pixel.AlphaBias!=0.0F) {
  341.       scaleOrBias = GL_TRUE;
  342.    }
  343.    else {
  344.       scaleOrBias = GL_FALSE;
  345.    }
  346.  
  347.    switch (image->Type) {
  348.       case GL_BITMAP:
  349.      {
  350.         GLint shift = ctx->Pixel.IndexShift;
  351.         GLint offset = ctx->Pixel.IndexOffset;
  352.         /* MapIto[RGBA]Size must be powers of two */
  353.         GLint rMask = ctx->Pixel.MapItoRsize-1;
  354.         GLint gMask = ctx->Pixel.MapItoGsize-1;
  355.         GLint bMask = ctx->Pixel.MapItoBsize-1;
  356.         GLint aMask = ctx->Pixel.MapItoAsize-1;
  357.         GLint i, j;
  358.         GLubyte *srcPtr = (GLubyte *) image->Data;
  359.  
  360.         assert( image->Format==GL_COLOR_INDEX );
  361.  
  362.         for (j=0; j<image->Height; j++) {
  363.            GLubyte bitMask = 128;
  364.            for (i=0; i<image->Width; i++) {
  365.           GLint index;
  366.           GLubyte red, green, blue, alpha;
  367.  
  368.           /* Fetch image color index */
  369.           index = (*srcPtr & bitMask) ? 1 : 0;
  370.           bitMask = bitMask >> 1;
  371.           if (bitMask==0) {
  372.              bitMask = 128;
  373.              srcPtr++;
  374.           }
  375.           /* apply index shift and offset */
  376.           if (shift>=0) {
  377.              index = (index << shift) + offset;
  378.           }
  379.           else {
  380.              index = (index >> -shift) + offset;
  381.           }
  382.           /* convert index to RGBA */
  383.           red   = (GLint) (ctx->Pixel.MapItoR[index & rMask] * 255.0F);
  384.           green = (GLint) (ctx->Pixel.MapItoG[index & gMask] * 255.0F);
  385.           blue  = (GLint) (ctx->Pixel.MapItoB[index & bMask] * 255.0F);
  386.           alpha = (GLint) (ctx->Pixel.MapItoA[index & aMask] * 255.0F);
  387.  
  388.           /* store texel (components are GLubytes in [0,255]) */
  389.           pixel = j * image->Width + i;
  390.           switch (texImage->Format) {
  391.              case GL_ALPHA:
  392.             texImage->Data[pixel] = alpha;
  393.             break;
  394.              case GL_LUMINANCE:
  395.             texImage->Data[pixel] = red;
  396.             break;
  397.              case GL_LUMINANCE_ALPHA:
  398.             texImage->Data[pixel*2+0] = red;
  399.             texImage->Data[pixel*2+1] = alpha;
  400.             break;
  401.              case GL_INTENSITY:
  402.             texImage->Data[pixel] = red;
  403.             break;
  404.              case GL_RGB:
  405.             texImage->Data[pixel*3+0] = red;
  406.             texImage->Data[pixel*3+1] = green;
  407.             texImage->Data[pixel*3+2] = blue;
  408.             break;
  409.              case GL_RGBA:
  410.             texImage->Data[pixel*4+0] = red;
  411.             texImage->Data[pixel*4+1] = green;
  412.             texImage->Data[pixel*4+2] = blue;
  413.             texImage->Data[pixel*4+3] = alpha;
  414.             break;
  415.              default:
  416.             gl_problem(ctx,"Bad format in image_to_texture");
  417.             return NULL;
  418.           }
  419.            }
  420.            if (bitMask!=128) {
  421.           srcPtr++;
  422.            }
  423.         }
  424.      }
  425.      break;
  426.  
  427.       case GL_UNSIGNED_BYTE:
  428.      for (pixel=0; pixel<numPixels; pixel++) {
  429.         GLubyte red, green, blue, alpha;
  430.         switch (image->Format) {
  431.            case GL_COLOR_INDEX:
  432.           if (decode_internal_format(internalFormat)==GL_COLOR_INDEX) {
  433.              /* a paletted texture */
  434.              GLint index = ((GLubyte*)image->Data)[pixel];
  435.              red = index;
  436.           }
  437.           else {
  438.              /* convert color index to RGBA */
  439.              GLint index = ((GLubyte*)image->Data)[pixel];
  440.              red   = (GLint) (255.0F * ctx->Pixel.MapItoR[index]);
  441.              green = (GLint) (255.0F * ctx->Pixel.MapItoG[index]);
  442.              blue  = (GLint) (255.0F * ctx->Pixel.MapItoB[index]);
  443.              alpha = (GLint) (255.0F * ctx->Pixel.MapItoA[index]);
  444.           }
  445.           break;
  446.            case GL_RGB:
  447.           /* Fetch image RGBA values */
  448.           red   = ((GLubyte*) image->Data)[pixel*3+0];
  449.           green = ((GLubyte*) image->Data)[pixel*3+1];
  450.           blue  = ((GLubyte*) image->Data)[pixel*3+2];
  451.           alpha = 255;
  452.           break;
  453.            case GL_RGBA:
  454.           red   = ((GLubyte*) image->Data)[pixel*4+0];
  455.           green = ((GLubyte*) image->Data)[pixel*4+1];
  456.           blue  = ((GLubyte*) image->Data)[pixel*4+2];
  457.           alpha = ((GLubyte*) image->Data)[pixel*4+3];
  458.           break;
  459.            case GL_RED:
  460.           red   = ((GLubyte*) image->Data)[pixel];
  461.           green = 0;
  462.           blue  = 0;
  463.           alpha = 255;
  464.           break;
  465.            case GL_GREEN:
  466.           red   = 0;
  467.           green = ((GLubyte*) image->Data)[pixel];
  468.           blue  = 0;
  469.           alpha = 255;
  470.           break;
  471.            case GL_BLUE:
  472.           red   = 0;
  473.           green = 0;
  474.           blue  = ((GLubyte*) image->Data)[pixel];
  475.           alpha = 255;
  476.           break;
  477.            case GL_ALPHA:
  478.           red   = 0;
  479.           green = 0;
  480.           blue  = 0;
  481.           alpha = ((GLubyte*) image->Data)[pixel];
  482.           break;
  483.            case GL_LUMINANCE: 
  484.           red   = ((GLubyte*) image->Data)[pixel];
  485.           green = red;
  486.           blue  = red;
  487.           alpha = 255;
  488.           break;
  489.           case GL_LUMINANCE_ALPHA:
  490.           red   = ((GLubyte*) image->Data)[pixel*2+0];
  491.           green = red;
  492.           blue  = red;
  493.           alpha = ((GLubyte*) image->Data)[pixel*2+1];
  494.           break;
  495.           default:
  496.          gl_problem(ctx,"Bad format (2) in image_to_texture");
  497.          return NULL;
  498.         }
  499.         
  500.         if (scaleOrBias || ctx->Pixel.MapColorFlag) {
  501.            /* Apply RGBA scale and bias */
  502.            GLfloat r = red   * (1.0F/255.0F);
  503.            GLfloat g = green * (1.0F/255.0F);
  504.            GLfloat b = blue  * (1.0F/255.0F);
  505.            GLfloat a = alpha * (1.0F/255.0F);
  506.            if (scaleOrBias) {
  507.           /* r,g,b,a now in [0,1] */
  508.           r = r * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
  509.           g = g * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
  510.           b = b * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
  511.           a = a * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
  512.           r = CLAMP( r, 0.0F, 1.0F );
  513.           g = CLAMP( g, 0.0F, 1.0F );
  514.           b = CLAMP( b, 0.0F, 1.0F );
  515.           a = CLAMP( a, 0.0F, 1.0F );
  516.            }
  517.            /* Apply pixel maps */
  518.            if (ctx->Pixel.MapColorFlag) {
  519.           GLint ir = (GLint) (r*ctx->Pixel.MapRtoRsize);
  520.           GLint ig = (GLint) (g*ctx->Pixel.MapGtoGsize);
  521.           GLint ib = (GLint) (b*ctx->Pixel.MapBtoBsize);
  522.           GLint ia = (GLint) (a*ctx->Pixel.MapAtoAsize);
  523.           r = ctx->Pixel.MapRtoR[ir];
  524.           g = ctx->Pixel.MapGtoG[ig];
  525.           b = ctx->Pixel.MapBtoB[ib];
  526.           a = ctx->Pixel.MapAtoA[ia];
  527.            }
  528.            red   = (GLint) (r * 255.0F);
  529.            green = (GLint) (g * 255.0F);
  530.            blue  = (GLint) (b * 255.0F);
  531.            alpha = (GLint) (a * 255.0F);
  532.         }
  533.  
  534.         /* store texel (components are GLubytes in [0,255]) */
  535.         switch (texImage->Format) {
  536.            case GL_COLOR_INDEX:
  537.           texImage->Data[pixel] = red; /* really an index */
  538.           break;
  539.            case GL_ALPHA:
  540.           texImage->Data[pixel] = alpha;
  541.           break;
  542.            case GL_LUMINANCE:
  543.           texImage->Data[pixel] = red;
  544.           break;
  545.            case GL_LUMINANCE_ALPHA:
  546.           texImage->Data[pixel*2+0] = red;
  547.           texImage->Data[pixel*2+1] = alpha;
  548.           break;
  549.            case GL_INTENSITY:
  550.           texImage->Data[pixel] = red;
  551.           break;
  552.            case GL_RGB:
  553.           texImage->Data[pixel*3+0] = red;
  554.           texImage->Data[pixel*3+1] = green;
  555.           texImage->Data[pixel*3+2] = blue;
  556.           break;
  557.            case GL_RGBA:
  558.           texImage->Data[pixel*4+0] = red;
  559.           texImage->Data[pixel*4+1] = green;
  560.           texImage->Data[pixel*4+2] = blue;
  561.           texImage->Data[pixel*4+3] = alpha;
  562.           break;
  563.            default:
  564.           gl_problem(ctx,"Bad format (3) in image_to_texture");
  565.           return NULL;
  566.         }
  567.      }
  568.      break;
  569.  
  570.       case GL_FLOAT:
  571.      for (pixel=0; pixel<numPixels; pixel++) {
  572.         GLfloat red, green, blue, alpha;
  573.         switch (texImage->Format) {
  574.            case GL_COLOR_INDEX:
  575.           if (decode_internal_format(internalFormat)==GL_COLOR_INDEX) {
  576.              /* a paletted texture */
  577.              GLint index = (GLint) ((GLfloat*) image->Data)[pixel];
  578.              red = index;
  579.           }
  580.           else {
  581.              GLint shift = ctx->Pixel.IndexShift;
  582.              GLint offset = ctx->Pixel.IndexOffset;
  583.              /* MapIto[RGBA]Size must be powers of two */
  584.              GLint rMask = ctx->Pixel.MapItoRsize-1;
  585.              GLint gMask = ctx->Pixel.MapItoGsize-1;
  586.              GLint bMask = ctx->Pixel.MapItoBsize-1;
  587.              GLint aMask = ctx->Pixel.MapItoAsize-1;
  588.              /* Fetch image color index */
  589.              GLint index = (GLint) ((GLfloat*) image->Data)[pixel];
  590.              /* apply index shift and offset */
  591.              if (shift>=0) {
  592.             index = (index << shift) + offset;
  593.              }
  594.              else {
  595.             index = (index >> -shift) + offset;
  596.              }
  597.              /* convert index to RGBA */
  598.              red   = ctx->Pixel.MapItoR[index & rMask];
  599.              green = ctx->Pixel.MapItoG[index & gMask];
  600.              blue  = ctx->Pixel.MapItoB[index & bMask];
  601.              alpha = ctx->Pixel.MapItoA[index & aMask];
  602.           }
  603.           break;
  604.            case GL_RGB:
  605.           /* Fetch image RGBA values */
  606.           red   = ((GLfloat*) image->Data)[pixel*3+0];
  607.           green = ((GLfloat*) image->Data)[pixel*3+1];
  608.           blue  = ((GLfloat*) image->Data)[pixel*3+2];
  609.           alpha = 1.0;
  610.           break;
  611.            case GL_RGBA:
  612.           red   = ((GLfloat*) image->Data)[pixel*4+0];
  613.           green = ((GLfloat*) image->Data)[pixel*4+1];
  614.           blue  = ((GLfloat*) image->Data)[pixel*4+2];
  615.           alpha = ((GLfloat*) image->Data)[pixel*4+3];
  616.           break;
  617.            case GL_RED:
  618.           red   = ((GLfloat*) image->Data)[pixel];
  619.           green = 0.0;
  620.           blue  = 0.0;
  621.           alpha = 1.0;
  622.           break;
  623.            case GL_GREEN:
  624.           red   = 0.0;
  625.           green = ((GLfloat*) image->Data)[pixel];
  626.           blue  = 0.0;
  627.           alpha = 1.0;
  628.           break;
  629.            case GL_BLUE:
  630.           red   = 0.0;
  631.           green = 0.0;
  632.           blue  = ((GLfloat*) image->Data)[pixel];
  633.           alpha = 1.0;
  634.           break;
  635.            case GL_ALPHA:
  636.           red   = 0.0;
  637.           green = 0.0;
  638.           blue  = 0.0;
  639.           alpha = ((GLfloat*) image->Data)[pixel];
  640.           break;
  641.            case GL_LUMINANCE: 
  642.           red   = ((GLfloat*) image->Data)[pixel];
  643.           green = red;
  644.           blue  = red;
  645.           alpha = 1.0;
  646.           break;
  647.           case GL_LUMINANCE_ALPHA:
  648.           red   = ((GLfloat*) image->Data)[pixel*2+0];
  649.           green = red;
  650.           blue  = red;
  651.           alpha = ((GLfloat*) image->Data)[pixel*2+1];
  652.           break;
  653.            default:
  654.           gl_problem(ctx,"Bad format (4) in image_to_texture");
  655.           return NULL;
  656.         }
  657.         
  658.         if (image->Format!=GL_COLOR_INDEX) {
  659.            /* Apply RGBA scale and bias */
  660.            if (scaleOrBias) {
  661.           red   = red   * ctx->Pixel.RedScale   + ctx->Pixel.RedBias;
  662.           green = green * ctx->Pixel.GreenScale + ctx->Pixel.GreenBias;
  663.           blue  = blue  * ctx->Pixel.BlueScale  + ctx->Pixel.BlueBias;
  664.           alpha = alpha * ctx->Pixel.AlphaScale + ctx->Pixel.AlphaBias;
  665.           red   = CLAMP( red,    0.0F, 1.0F );
  666.           green = CLAMP( green,  0.0F, 1.0F );
  667.           blue  = CLAMP( blue,   0.0F, 1.0F );
  668.           alpha = CLAMP( alpha,  0.0F, 1.0F );
  669.            }
  670.            /* Apply pixel maps */
  671.            if (ctx->Pixel.MapColorFlag) {
  672.           GLint ir = (GLint) (red  *ctx->Pixel.MapRtoRsize);
  673.           GLint ig = (GLint) (green*ctx->Pixel.MapGtoGsize);
  674.           GLint ib = (GLint) (blue *ctx->Pixel.MapBtoBsize);
  675.           GLint ia = (GLint) (alpha*ctx->Pixel.MapAtoAsize);
  676.           red   = ctx->Pixel.MapRtoR[ir];
  677.           green = ctx->Pixel.MapGtoG[ig];
  678.           blue  = ctx->Pixel.MapBtoB[ib];
  679.           alpha = ctx->Pixel.MapAtoA[ia];
  680.            }
  681.         }
  682.  
  683.         /* store texel (components are GLubytes in [0,255]) */
  684.         switch (texImage->Format) {
  685.            case GL_COLOR_INDEX:
  686.           /* a paletted texture */
  687.           texImage->Data[pixel] = (GLint) (red * 255.0F);
  688.           break;
  689.            case GL_ALPHA:
  690.           texImage->Data[pixel] = (GLint) (alpha * 255.0F);
  691.           break;
  692.            case GL_LUMINANCE:
  693.           texImage->Data[pixel] = (GLint) (red * 255.0F);
  694.           break;
  695.            case GL_LUMINANCE_ALPHA:
  696.           texImage->Data[pixel*2+0] = (GLint) (red * 255.0F);
  697.           texImage->Data[pixel*2+1] = (GLint) (alpha * 255.0F);
  698.           break;
  699.            case GL_INTENSITY:
  700.           texImage->Data[pixel] = (GLint) (red * 255.0F);
  701.           break;
  702.            case GL_RGB:
  703.           texImage->Data[pixel*3+0] = (GLint) (red   * 255.0F);
  704.           texImage->Data[pixel*3+1] = (GLint) (green * 255.0F);
  705.           texImage->Data[pixel*3+2] = (GLint) (blue  * 255.0F);
  706.           break;
  707.            case GL_RGBA:
  708.           texImage->Data[pixel*4+0] = (GLint) (red   * 255.0F);
  709.           texImage->Data[pixel*4+1] = (GLint) (green * 255.0F);
  710.           texImage->Data[pixel*4+2] = (GLint) (blue  * 255.0F);
  711.           texImage->Data[pixel*4+3] = (GLint) (alpha * 255.0F);
  712.           break;
  713.            default:
  714.           gl_problem(ctx,"Bad format (5) in image_to_texture");
  715.           return NULL;
  716.         }
  717.      }
  718.      break;
  719.  
  720.       default:
  721.      gl_problem(ctx, "Bad image type in image_to_texture");
  722.      return NULL;
  723.    }
  724.  
  725.    return texImage;
  726. }
  727.  
  728.  
  729.  
  730. /*
  731.  * glTexImage[123]D can accept a NULL image pointer.  In this case we
  732.  * create a texture image with unspecified image contents per the OpenGL
  733.  * spec.
  734.  */
  735. static struct gl_texture_image *
  736. make_null_texture( GLcontext *ctx, GLenum internalFormat,
  737.            GLsizei width, GLsizei height, GLsizei depth, GLint border )
  738. {
  739.    GLint components;
  740.    struct gl_texture_image *texImage;
  741.    GLint numPixels;
  742.    (void) ctx;
  743.  
  744.    /*internalFormat = decode_internal_format(internalFormat);*/
  745.    components = components_in_intformat(internalFormat);
  746.    numPixels = width * height * depth;
  747.  
  748.    texImage = gl_alloc_texture_image();
  749.    if (!texImage)
  750.       return NULL;
  751.  
  752.    texImage->Format = (GLenum) decode_internal_format(internalFormat);
  753.    texImage->IntFormat = internalFormat;
  754.    texImage->Border = border;
  755.    texImage->Width = width;
  756.    texImage->Height = height;
  757.    texImage->Depth = depth;
  758.    texImage->WidthLog2 = logbase2(width - 2*border);
  759.    if (height==1)  /* 1-D texture */
  760.       texImage->HeightLog2 = 0;
  761.    else
  762.       texImage->HeightLog2 = logbase2(height - 2*border);
  763.    if (depth==1)   /* 2-D texture */
  764.       texImage->DepthLog2 = 0;
  765.    else
  766.       texImage->DepthLog2 = logbase2(depth - 2*border);
  767.    texImage->Width2 = 1 << texImage->WidthLog2;
  768.    texImage->Height2 = 1 << texImage->HeightLog2;
  769.    texImage->Depth2 = 1 << texImage->DepthLog2;
  770.    texImage->MaxLog2 = MAX2( texImage->WidthLog2, texImage->HeightLog2 );
  771.  
  772.    /* XXX should we really allocate memory for the image or let it be NULL? */
  773.    /*texImage->Data = NULL;*/
  774.  
  775.    texImage->Data = (GLubyte *) malloc( numPixels * components );
  776.  
  777.    /*
  778.     * Let's see if anyone finds this.  If glTexImage2D() is called with
  779.     * a NULL image pointer then load the texture image with something
  780.     * interesting instead of leaving it indeterminate.
  781.     */
  782.    if (texImage->Data) {
  783.       char message[8][32] = {
  784.      "   X   X  XXXXX   XXX     X    ",
  785.      "   XX XX  X      X   X   X X   ",
  786.      "   X X X  X      X      X   X  ",
  787.      "   X   X  XXXX    XXX   XXXXX  ",
  788.      "   X   X  X          X  X   X  ",
  789.      "   X   X  X      X   X  X   X  ",
  790.      "   X   X  XXXXX   XXX   X   X  ",
  791.      "                               "
  792.       };
  793.  
  794.       GLubyte *imgPtr = texImage->Data;
  795.       GLint i, j, k;
  796.       for (i=0;i<height;i++) {
  797.      GLint srcRow = 7 - i % 8;
  798.      for (j=0;j<width;j++) {
  799.         GLint srcCol = j % 32;
  800.         GLubyte texel = (message[srcRow][srcCol]=='X') ? 255 : 70;
  801.         for (k=0;k<components;k++) {
  802.            *imgPtr++ = texel;
  803.         }
  804.      }
  805.       }
  806.    }
  807.  
  808.    return texImage;
  809. }
  810.  
  811.  
  812.  
  813.  
  814. /*
  815.  * Test glTexImagee1D() parameters for errors.
  816.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  817.  */
  818. static GLboolean texture_1d_error_check( GLcontext *ctx, GLenum target,
  819.                      GLint level, GLint internalFormat,
  820.                      GLenum format, GLenum type,
  821.                      GLint width, GLint border )
  822. {
  823.    GLint iformat;
  824.    if (target!=GL_TEXTURE_1D && target!=GL_PROXY_TEXTURE_1D) {
  825.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D" );
  826.       return GL_TRUE;
  827.    }
  828.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  829.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(level)" );
  830.       return GL_TRUE;
  831.    }
  832.    iformat = decode_internal_format( internalFormat );
  833.    if (iformat<0) {
  834.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(internalFormat)" );
  835.       return GL_TRUE;
  836.    }
  837.    if (border!=0 && border!=1) {
  838.       if (target!=GL_PROXY_TEXTURE_1D) {
  839.      gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(border)" );
  840.       }
  841.       return GL_TRUE;
  842.    }
  843.    if (width<2*border || width>2+MAX_TEXTURE_SIZE) {
  844.       if (target!=GL_PROXY_TEXTURE_1D) {
  845.      gl_error( ctx, GL_INVALID_VALUE, "glTexImage1D(width)" );
  846.       }
  847.       return GL_TRUE;
  848.    }
  849.    if (logbase2( width-2*border )<0) {
  850.       gl_error( ctx, GL_INVALID_VALUE,
  851.            "glTexImage1D(width != 2^k + 2*border)");
  852.       return GL_TRUE;
  853.    }
  854.    switch (format) {
  855.       case GL_COLOR_INDEX:
  856.       case GL_RED:
  857.       case GL_GREEN:
  858.       case GL_BLUE:
  859.       case GL_ALPHA:
  860.       case GL_RGB:
  861.       case GL_RGBA:
  862.       case GL_LUMINANCE:
  863.       case GL_LUMINANCE_ALPHA:
  864.       case GL_ABGR_EXT:
  865.      /* OK */
  866.      break;
  867.       default:
  868.      gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(format)" );
  869.      return GL_TRUE;
  870.    }
  871.    switch (type) {
  872.       case GL_UNSIGNED_BYTE:
  873.       case GL_BYTE:
  874.       case GL_UNSIGNED_SHORT:
  875.       case GL_SHORT:
  876.       case GL_UNSIGNED_INT:
  877.       case GL_INT:
  878.       case GL_FLOAT:
  879.      /* OK */
  880.      break;
  881.       default:
  882.      gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(type)" );
  883.      return GL_TRUE;
  884.    }
  885.    return GL_FALSE;
  886. }
  887.  
  888.  
  889. /*
  890.  * Test glTexImagee2D() parameters for errors.
  891.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  892.  */
  893. static GLboolean texture_2d_error_check( GLcontext *ctx, GLenum target,
  894.                      GLint level, GLint internalFormat,
  895.                      GLenum format, GLenum type,
  896.                      GLint width, GLint height,
  897.                      GLint border )
  898. {
  899.    GLint iformat;
  900.    if (target!=GL_TEXTURE_2D && target!=GL_PROXY_TEXTURE_2D) {
  901.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
  902.       return GL_TRUE;
  903.    }
  904.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  905.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(level)" );
  906.       return GL_TRUE;
  907.    }
  908.    iformat = decode_internal_format( internalFormat );
  909.    if (iformat<0) {
  910.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(internalFormat)" );
  911.       return GL_TRUE;
  912.    }
  913.    if (border!=0 && border!=1) {
  914.       if (target!=GL_PROXY_TEXTURE_2D) {
  915.      gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(border)" );
  916.       }
  917.       return GL_TRUE;
  918.    }
  919.    if (width<2*border || width>2+MAX_TEXTURE_SIZE) {
  920.       if (target!=GL_PROXY_TEXTURE_2D) {
  921.      gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(width)" );
  922.       }
  923.       return GL_TRUE;
  924.    }
  925.    if (height<2*border || height>2+MAX_TEXTURE_SIZE) {
  926.       if (target!=GL_PROXY_TEXTURE_2D) {
  927.      gl_error( ctx, GL_INVALID_VALUE, "glTexImage2D(height)" );
  928.       }
  929.       return GL_TRUE;
  930.    }
  931.    if (logbase2( width-2*border )<0) {
  932.       gl_error( ctx,GL_INVALID_VALUE,
  933.            "glTexImage2D(width != 2^k + 2*border)");
  934.       return GL_TRUE;
  935.    }
  936.    if (logbase2( height-2*border )<0) {
  937.       gl_error( ctx,GL_INVALID_VALUE,
  938.            "glTexImage2D(height != 2^k + 2*border)");
  939.       return GL_TRUE;
  940.    }
  941.    switch (format) {
  942.       case GL_COLOR_INDEX:
  943.       case GL_RED:
  944.       case GL_GREEN:
  945.       case GL_BLUE:
  946.       case GL_ALPHA:
  947.       case GL_RGB:
  948.       case GL_RGBA:
  949.       case GL_LUMINANCE:
  950.       case GL_LUMINANCE_ALPHA:
  951.       case GL_ABGR_EXT:
  952.      /* OK */
  953.      break;
  954.       default:
  955.      gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(format)" );
  956.      return GL_TRUE;
  957.    }
  958.    switch (type) {
  959.       case GL_UNSIGNED_BYTE:
  960.       case GL_BYTE:
  961.       case GL_UNSIGNED_SHORT:
  962.       case GL_SHORT:
  963.       case GL_UNSIGNED_INT:
  964.       case GL_INT:
  965.       case GL_FLOAT:
  966.      /* OK */
  967.      break;
  968.       default:
  969.      gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(type)" );
  970.      return GL_TRUE;
  971.    }
  972.    return GL_FALSE;
  973. }
  974.  
  975.  
  976. /*
  977.  * Test glTexImage3DEXT() parameters for errors.
  978.  * Return:  GL_TRUE = an error was detected, GL_FALSE = no errors
  979.  */
  980. static GLboolean texture_3d_error_check( GLcontext *ctx, GLenum target,
  981.                      GLint level, GLint internalFormat,
  982.                      GLenum format, GLenum type,
  983.                      GLint width, GLint height,
  984.                      GLint depth, GLint border )
  985. {
  986.    GLint iformat;
  987.    if (target!=GL_TEXTURE_3D_EXT && target!=GL_PROXY_TEXTURE_3D_EXT) {
  988.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(target)" );
  989.       return GL_TRUE;
  990.    }
  991.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  992.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(level)" );
  993.       return GL_TRUE;
  994.    }
  995.    iformat = decode_internal_format( internalFormat );
  996.    if (iformat<0) {
  997.       gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(internalFormat)" );
  998.       return GL_TRUE;
  999.    }
  1000.    if (border!=0 && border!=1) {
  1001.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  1002.      gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(border)" );
  1003.       }
  1004.       return GL_TRUE;
  1005.    }
  1006.    if (width<2*border || width>2+MAX_TEXTURE_SIZE) {
  1007.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  1008.      gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(width)" );
  1009.       }
  1010.       return GL_TRUE;
  1011.    }
  1012.    if (height<2*border || height>2+MAX_TEXTURE_SIZE) {
  1013.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  1014.      gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(height)" );
  1015.       }
  1016.       return GL_TRUE;
  1017.    }
  1018.    if (depth<2*border || depth>2+MAX_TEXTURE_SIZE) {
  1019.       if (target!=GL_PROXY_TEXTURE_3D_EXT) {
  1020.      gl_error( ctx, GL_INVALID_VALUE, "glTexImage3DEXT(depth)" );
  1021.       }
  1022.       return GL_TRUE;
  1023.    }
  1024.    if (logbase2( width-2*border )<0) {
  1025.       gl_error( ctx,GL_INVALID_VALUE,
  1026.            "glTexImage3DEXT(width != 2^k + 2*border))");
  1027.       return GL_TRUE;
  1028.    }
  1029.    if (logbase2( height-2*border )<0) {
  1030.       gl_error( ctx,GL_INVALID_VALUE,
  1031.            "glTexImage3DEXT(height != 2^k + 2*border))");
  1032.       return GL_TRUE;
  1033.    }
  1034.    if (logbase2( depth-2*border )<0) {
  1035.       gl_error( ctx,GL_INVALID_VALUE,
  1036.            "glTexImage3DEXT(depth  != 2^k + 2*border))");
  1037.       return GL_TRUE;
  1038.    }
  1039.    switch (format) {
  1040.       case GL_COLOR_INDEX:
  1041.       case GL_RED:
  1042.       case GL_GREEN:
  1043.       case GL_BLUE:
  1044.       case GL_ALPHA:
  1045.       case GL_RGB:
  1046.       case GL_RGBA:
  1047.       case GL_LUMINANCE:
  1048.       case GL_LUMINANCE_ALPHA:
  1049.       case GL_ABGR_EXT:
  1050.      /* OK */
  1051.      break;
  1052.       default:
  1053.      gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(format)" );
  1054.      return GL_TRUE;
  1055.    }
  1056.    switch (type) {
  1057.       case GL_UNSIGNED_BYTE:
  1058.       case GL_BYTE:
  1059.       case GL_UNSIGNED_SHORT:
  1060.       case GL_SHORT:
  1061.       case GL_UNSIGNED_INT:
  1062.       case GL_INT:
  1063.       case GL_FLOAT:
  1064.      /* OK */
  1065.      break;
  1066.       default:
  1067.      gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(type)" );
  1068.      return GL_TRUE;
  1069.    }
  1070.    return GL_FALSE;
  1071. }
  1072.  
  1073.  
  1074.  
  1075. /*
  1076.  * Called from the API.  Note that width includes the border.
  1077.  */
  1078. void gl_TexImage1D( GLcontext *ctx,
  1079.             GLenum target, GLint level, GLint internalformat,
  1080.             GLsizei width, GLint border, GLenum format,
  1081.             GLenum type, struct gl_image *image )
  1082. {
  1083.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  1084.    if (INSIDE_BEGIN_END(ctx)) {
  1085.       gl_error( ctx, GL_INVALID_OPERATION, "glTexImage1D" );
  1086.       return;
  1087.    }
  1088.  
  1089.    if (target==GL_TEXTURE_1D) {
  1090.       struct gl_texture_image *teximage;
  1091.       if (texture_1d_error_check( ctx, target, level, internalformat,
  1092.                   format, type, width, border )) {
  1093.      /* error in texture image was detected */
  1094.      return;
  1095.       }
  1096.  
  1097.       /* free current texture image, if any */
  1098.       if (texSet->Current1D->Image[level]) {
  1099.      gl_free_texture_image( texSet->Current1D->Image[level] );
  1100.       }
  1101.  
  1102.       /* make new texture from source image */
  1103.       if (image) {
  1104.      teximage = image_to_texture(ctx, image, internalformat, border);
  1105.       }
  1106.       else {
  1107.      teximage = make_null_texture(ctx, (GLenum) internalformat,
  1108.                       width, 1, 1, border);
  1109.       }
  1110.  
  1111.       /* install new texture image */
  1112.       texSet->Current1D->Image[level] = teximage;
  1113.       texSet->Current1D->Dirty = GL_TRUE;
  1114.       ctx->Texture.AnyDirty = GL_TRUE;
  1115.       ctx->NewState |= NEW_TEXTURING;
  1116.  
  1117.       /* free the source image */
  1118.       if (image && image->RefCount==0) {
  1119.      /* if RefCount>0 then image must be in a display list */
  1120.      gl_free_image(image);
  1121.       }
  1122.  
  1123.       /* tell driver about change */
  1124.       if (ctx->Driver.TexImage) {
  1125.      (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D,
  1126.                   texSet->Current1D,
  1127.                   level, internalformat, teximage );
  1128.       }
  1129.    }
  1130.    else if (target==GL_PROXY_TEXTURE_1D) {
  1131.       /* Proxy texture: check for errors and update proxy state */
  1132.       if (texture_1d_error_check( ctx, target, level, internalformat,
  1133.                   format, type, width, border )) {
  1134.      if (level>=0 && level<MAX_TEXTURE_LEVELS) {
  1135.         MEMSET( ctx->Texture.Proxy1D->Image[level], 0,
  1136.             sizeof(struct gl_texture_image) );
  1137.      }
  1138.       }
  1139.       else {
  1140.      ctx->Texture.Proxy1D->Image[level]->Format = (GLenum) internalformat;
  1141. #ifdef BUGFIX
  1142.      ctx->Texture.Proxy1D->Image[level]->IntFormat = (GLenum) internalformat;
  1143. #endif
  1144.      ctx->Texture.Proxy1D->Image[level]->Border = border;
  1145.      ctx->Texture.Proxy1D->Image[level]->Width = width;
  1146.      ctx->Texture.Proxy1D->Image[level]->Height = 1;
  1147.       }
  1148.       if (image && image->RefCount==0) {
  1149.      /* if RefCount>0 then image must be in a display list */
  1150.      gl_free_image(image);
  1151.       }
  1152.    }
  1153.    else {
  1154.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage1D(target)" );
  1155.       return;
  1156.    }
  1157. }
  1158.  
  1159.  
  1160.  
  1161.  
  1162. /*
  1163.  * Called by the API or display list executor.
  1164.  * Note that width and height include the border.
  1165.  */
  1166. void gl_TexImage2D( GLcontext *ctx,
  1167.             GLenum target, GLint level, GLint internalformat,
  1168.             GLsizei width, GLsizei height, GLint border,
  1169.             GLenum format, GLenum type,
  1170.             struct gl_image *image )
  1171. {
  1172.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  1173.    if (INSIDE_BEGIN_END(ctx)) {
  1174.       gl_error( ctx, GL_INVALID_OPERATION, "glTexImage2D" );
  1175.       return;
  1176.    }
  1177.  
  1178.    if (target==GL_TEXTURE_2D) {
  1179.       struct gl_texture_image *teximage;
  1180.       if (texture_2d_error_check( ctx, target, level, internalformat,
  1181.                   format, type, width, height, border )) {
  1182.      /* error in texture image was detected */
  1183.      return;
  1184.       }
  1185.  
  1186.       /* free current texture image, if any */
  1187.       if (texSet->Current2D->Image[level]) {
  1188.      gl_free_texture_image( texSet->Current2D->Image[level] );
  1189.       }
  1190.       /* make new texture from source image */
  1191.       if (image) {
  1192.      teximage = image_to_texture(ctx, image, internalformat, border);
  1193.       }
  1194.       else {
  1195.      teximage = make_null_texture(ctx, (GLenum) internalformat,
  1196.                       width, height, 1, border);
  1197.       }
  1198.  
  1199.       /* install new texture image */
  1200.       texSet->Current2D->Image[level] = teximage;
  1201.       texSet->Current2D->Dirty = GL_TRUE;
  1202.       ctx->Texture.AnyDirty = GL_TRUE;
  1203.       ctx->NewState |= NEW_TEXTURING;
  1204.  
  1205.       /* free the source image */
  1206.       if (image && image->RefCount==0) {
  1207.      /* if RefCount>0 then image must be in a display list */
  1208.      gl_free_image(image);
  1209.       }
  1210.  
  1211.       /* tell driver about change */
  1212.       if (ctx->Driver.TexImage) {
  1213.      (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D,
  1214.                   texSet->Current2D,
  1215.                   level, internalformat, teximage );
  1216.       }
  1217.    }
  1218.    else if (target==GL_PROXY_TEXTURE_2D) {
  1219.       /* Proxy texture: check for errors and update proxy state */
  1220.       if (texture_2d_error_check( ctx, target, level, internalformat,
  1221.                   format, type, width, height, border )) {
  1222.      if (level>=0 && level<MAX_TEXTURE_LEVELS) {
  1223.         MEMSET( ctx->Texture.Proxy2D->Image[level], 0,
  1224.             sizeof(struct gl_texture_image) );
  1225.      }
  1226.       }
  1227.       else {
  1228.      ctx->Texture.Proxy2D->Image[level]->Format = (GLenum) internalformat;
  1229. #ifdef BUGFIX
  1230.      ctx->Texture.Proxy2D->Image[level]->IntFormat = (GLenum) internalformat;
  1231. #endif
  1232.      ctx->Texture.Proxy2D->Image[level]->Border = border;
  1233.      ctx->Texture.Proxy2D->Image[level]->Width = width;
  1234.      ctx->Texture.Proxy2D->Image[level]->Height = height;
  1235.       }
  1236.       if (image && image->RefCount==0) {
  1237.      /* if RefCount>0 then image must be in a display list */
  1238.      gl_free_image(image);
  1239.       }
  1240.    }
  1241.    else {
  1242.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage2D(target)" );
  1243.       return;
  1244.    }
  1245. }
  1246.  
  1247.  
  1248.  
  1249. /*
  1250.  * Called by the API or display list executor.
  1251.  * Note that width and height include the border.
  1252.  */
  1253. void gl_TexImage3DEXT( GLcontext *ctx,
  1254.                GLenum target, GLint level, GLint internalformat,
  1255.                GLsizei width, GLsizei height, GLsizei depth,
  1256.                GLint border, GLenum format, GLenum type,
  1257.                struct gl_image *image )
  1258. {
  1259.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  1260.    if (INSIDE_BEGIN_END(ctx)) {
  1261.       gl_error( ctx, GL_INVALID_OPERATION, "glTexImage3DEXT" );
  1262.       return;
  1263.    }
  1264.  
  1265.    if (target==GL_TEXTURE_3D_EXT) {
  1266.       struct gl_texture_image *teximage;
  1267.       if (texture_3d_error_check( ctx, target, level, internalformat,
  1268.                   format, type, width, height, depth,
  1269.                   border )) {
  1270.      /* error in texture image was detected */
  1271.      return;
  1272.       }
  1273.  
  1274.       /* free current texture image, if any */
  1275.       if (texSet->Current3D->Image[level]) {
  1276.      gl_free_texture_image( texSet->Current3D->Image[level] );
  1277.       }
  1278.  
  1279.       /* make new texture from source image */
  1280.       if (image) {
  1281.      teximage = image_to_texture(ctx, image, internalformat, border);
  1282.       }
  1283.       else {
  1284.      teximage = make_null_texture(ctx, (GLenum) internalformat,
  1285.                       width, height, depth, border);
  1286.       }
  1287.  
  1288.       /* install new texture image */
  1289.       texSet->Current3D->Image[level] = teximage;
  1290.       texSet->Current3D->Dirty = GL_TRUE;
  1291.       ctx->Texture.AnyDirty = GL_TRUE;
  1292.       ctx->NewState |= NEW_TEXTURING;
  1293.  
  1294.       /* free the source image */
  1295.       if (image && image->RefCount==0) {
  1296.      /* if RefCount>0 then image must be in a display list */
  1297.      gl_free_image(image);
  1298.       }
  1299.  
  1300.       /* tell driver about change */
  1301.       if (ctx->Driver.TexImage) {
  1302.      (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT,
  1303.                   texSet->Current3D,
  1304.                   level, internalformat, teximage );
  1305.       }
  1306.    }
  1307.    else if (target==GL_PROXY_TEXTURE_3D_EXT) {
  1308.       /* Proxy texture: check for errors and update proxy state */
  1309.       if (texture_3d_error_check( ctx, target, level, internalformat,
  1310.                   format, type, width, height, depth,
  1311.                   border )) {
  1312.      if (level>=0 && level<MAX_TEXTURE_LEVELS) {
  1313.         MEMSET( ctx->Texture.Proxy3D->Image[level], 0,
  1314.             sizeof(struct gl_texture_image) );
  1315.      }
  1316.       }
  1317.       else {
  1318.      ctx->Texture.Proxy3D->Image[level]->Format = (GLenum) internalformat;
  1319. #ifdef BUGFIX
  1320.      ctx->Texture.Proxy3D->Image[level]->IntFormat = (GLenum) internalformat;
  1321. #endif
  1322.      ctx->Texture.Proxy3D->Image[level]->Border = border;
  1323.      ctx->Texture.Proxy3D->Image[level]->Width = width;
  1324.      ctx->Texture.Proxy3D->Image[level]->Height = height;
  1325.      ctx->Texture.Proxy3D->Image[level]->Depth  = depth;
  1326.       }
  1327.       if (image && image->RefCount==0) {
  1328.      /* if RefCount>0 then image must be in a display list */
  1329.      gl_free_image(image);
  1330.       }
  1331.    }
  1332.    else {
  1333.       gl_error( ctx, GL_INVALID_ENUM, "glTexImage3DEXT(target)" );
  1334.       return;
  1335.    }
  1336. }
  1337.  
  1338.  
  1339.  
  1340. void gl_GetTexImage( GLcontext *ctx, GLenum target, GLint level, GLenum format,
  1341.              GLenum type, GLvoid *pixels )
  1342. {
  1343.    const struct gl_texture_object *texObj;
  1344.  
  1345.    if (INSIDE_BEGIN_END(ctx)) {
  1346.       gl_error( ctx, GL_INVALID_OPERATION, "glGetTexImage" );
  1347.       return;
  1348.    }
  1349.  
  1350.    if (level < 0 || level >= MAX_TEXTURE_LEVELS) {
  1351.       gl_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
  1352.       return;
  1353.    }
  1354.  
  1355.    if (gl_sizeof_type(type) <= 0) {
  1356.       gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
  1357.       return;
  1358.    }
  1359.  
  1360.    if (gl_components_in_format(format) <= 0) {
  1361.       gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
  1362.       return;
  1363.    }
  1364.  
  1365.    if (!pixels)
  1366.       return;  /* XXX generate an error??? */
  1367.  
  1368.    switch (target) {
  1369.       case GL_TEXTURE_1D:
  1370.      texObj = ctx->Texture.Set[ctx->Texture.CurrentSet].Current1D;
  1371.      break;
  1372.       case GL_TEXTURE_2D:
  1373.      texObj = ctx->Texture.Set[ctx->Texture.CurrentSet].Current2D;
  1374.      break;
  1375.       case GL_TEXTURE_3D:
  1376.      texObj = ctx->Texture.Set[ctx->Texture.CurrentSet].Current3D;
  1377.      break;
  1378.       default:
  1379.      gl_error( ctx, GL_INVALID_ENUM, "glGetTexImage(target)" );
  1380.      return;
  1381.    }
  1382.  
  1383.    if (texObj->Image[level] && texObj->Image[level]->Data) {
  1384.       const struct gl_texture_image *texImage = texObj->Image[level];
  1385.       GLint width = texImage->Width;
  1386.       GLint height = texImage->Height;
  1387.       GLint row;
  1388.  
  1389.       for (row = 0; row < height; row++) {
  1390.      /* compute destination address in client memory */
  1391.      GLvoid *dest = gl_pixel_addr_in_image( &ctx->Unpack, pixels,
  1392.                         width, height,
  1393.                         format, type, 0, row, 0);
  1394.  
  1395.      assert(dest);
  1396.      if (texImage->Format == GL_RGBA) {
  1397.         const GLubyte *src = texImage->Data + row * width * 4 * sizeof(GLubyte);
  1398.         gl_pack_rgba_span( ctx, width, (void *) src, format, type, dest );
  1399.      }
  1400.      else {
  1401.         /* fetch RGBA row from texture image then pack it in client mem */
  1402.         GLubyte rgba[MAX_WIDTH][4];
  1403.         GLint i;
  1404.         const GLubyte *src;
  1405.         switch (texImage->Format) {
  1406.            case GL_ALPHA:
  1407.           src = texImage->Data + row * width * sizeof(GLubyte);
  1408.           for (i = 0; i < width; i++) {
  1409.              rgba[i][RCOMP] = 255;
  1410.              rgba[i][GCOMP] = 255;
  1411.              rgba[i][BCOMP] = 255;
  1412.              rgba[i][ACOMP] = src[i];
  1413.           }
  1414.           break;
  1415.            case GL_LUMINANCE:
  1416.           src = texImage->Data + row * width * sizeof(GLubyte);
  1417.           for (i = 0; i < width; i++) {
  1418.              rgba[i][RCOMP] = src[i];
  1419.              rgba[i][GCOMP] = src[i];
  1420.              rgba[i][BCOMP] = src[i];
  1421.              rgba[i][ACOMP] = 255;
  1422.            }
  1423.           break;
  1424.            case GL_LUMINANCE_ALPHA:
  1425.           src = texImage->Data + row * 2 * width * sizeof(GLubyte);
  1426.           for (i = 0; i < width; i++) {
  1427.              rgba[i][RCOMP] = src[i*2+0];
  1428.              rgba[i][GCOMP] = src[i*2+0];
  1429.              rgba[i][BCOMP] = src[i*2+0];
  1430.              rgba[i][ACOMP] = src[i*2+1];
  1431.           }
  1432.           break;
  1433.            case GL_INTENSITY:
  1434.           src = texImage->Data + row * width * sizeof(GLubyte);
  1435.           for (i = 0; i < width; i++) {
  1436.              rgba[i][RCOMP] = src[i];
  1437.              rgba[i][GCOMP] = src[i];
  1438.              rgba[i][BCOMP] = src[i];
  1439.              rgba[i][ACOMP] = 255;
  1440.           }
  1441.           break;
  1442.            case GL_RGB:
  1443.           src = texImage->Data + row * 3 * width * sizeof(GLubyte);
  1444.           for (i = 0; i < width; i++) {
  1445.              rgba[i][RCOMP] = src[i*3+0];
  1446.              rgba[i][GCOMP] = src[i*3+1];
  1447.              rgba[i][BCOMP] = src[i*3+2];
  1448.              rgba[i][ACOMP] = 255;
  1449.           }
  1450.           break;
  1451.            case GL_RGBA:
  1452.           /* this special case should have been handled above! */
  1453.           gl_problem( ctx, "error 1 in gl_GetTexImage" );
  1454.           break;
  1455.            case GL_COLOR_INDEX:
  1456.           gl_problem( ctx, "GL_COLOR_INDEX not implemented in gl_GetTexImage" );
  1457.           break;
  1458.            default:
  1459.           gl_problem( ctx, "bad format in gl_GetTexImage" );
  1460.         }
  1461. #ifndef __STORM__
  1462.         gl_pack_rgba_span( ctx, width, rgba, format, type, dest );
  1463. #else
  1464.         gl_pack_rgba_span( ctx, width, (CONST GLubyte(*)[4])rgba, format, type, dest );
  1465. #endif
  1466.      }
  1467.       }
  1468.    }
  1469. }
  1470.  
  1471.  
  1472.  
  1473. /*
  1474.  * Unpack the image data given to glTexSubImage[12]D.
  1475.  * This function is just a wrapper for gl_unpack_image() but it does
  1476.  * some extra error checking.
  1477.  */
  1478. struct gl_image *
  1479. gl_unpack_texsubimage( GLcontext *ctx, GLint width, GLint height,
  1480.                GLenum format, GLenum type, const GLvoid *pixels )
  1481. {
  1482.    if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1483.       return NULL;
  1484.    }
  1485.  
  1486.    if (format==GL_STENCIL_INDEX || format==GL_DEPTH_COMPONENT){
  1487.       return NULL;
  1488.    }
  1489.  
  1490.    if (gl_sizeof_type(type)<=0) {
  1491.       return NULL;
  1492.    }
  1493.  
  1494.    return gl_unpack_image3D( ctx, width, height, 1, format, type, pixels );
  1495. }
  1496.  
  1497.  
  1498. /*
  1499.  * Unpack the image data given to glTexSubImage3D.
  1500.  * This function is just a wrapper for gl_unpack_image() but it does
  1501.  * some extra error checking.
  1502.  */
  1503. struct gl_image *
  1504. gl_unpack_texsubimage3D( GLcontext *ctx, GLint width, GLint height, GLint depth,
  1505.              GLenum format, GLenum type, const GLvoid *pixels )
  1506. {
  1507.    if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1508.       return NULL;
  1509.    }
  1510.  
  1511.    if (format==GL_STENCIL_INDEX || format==GL_DEPTH_COMPONENT){
  1512.       return NULL;
  1513.    }
  1514.  
  1515.    if (gl_sizeof_type(type)<=0) {
  1516.       return NULL;
  1517.    }
  1518.  
  1519.    return gl_unpack_image3D( ctx, width, height, depth, format, type, pixels );
  1520. }
  1521.  
  1522.  
  1523.  
  1524. void gl_TexSubImage1D( GLcontext *ctx,
  1525.                GLenum target, GLint level, GLint xoffset,
  1526.                GLsizei width, GLenum format, GLenum type,
  1527.                struct gl_image *image )
  1528. {
  1529.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  1530.    struct gl_texture_image *destTex;
  1531.  
  1532.    if (target!=GL_TEXTURE_1D) {
  1533.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(target)" );
  1534.       return;
  1535.    }
  1536.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1537.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(level)" );
  1538.       return;
  1539.    }
  1540.  
  1541.    destTex = texSet->Current1D->Image[level];
  1542.    if (!destTex) {
  1543.       gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage1D" );
  1544.       return;
  1545.    }
  1546.  
  1547.    if (xoffset < -((GLint)destTex->Border)) {
  1548.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(xoffset)" );
  1549.       return;
  1550.    }
  1551.    if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
  1552.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(xoffset+width)" );
  1553.       return;
  1554.    }
  1555.  
  1556.    if (image) {
  1557.       /* unpacking must have been error-free */
  1558.       GLint texcomponents = components_in_intformat(destTex->Format);
  1559.  
  1560.       if (image->Type==GL_UNSIGNED_BYTE && texcomponents==image->Components) {
  1561.      /* Simple case, just byte copy image data into texture image */
  1562.      /* row by row. */
  1563.      GLubyte *dst = destTex->Data + texcomponents * xoffset;
  1564.      GLubyte *src = (GLubyte *) image->Data;
  1565.      MEMCPY( dst, src, width * texcomponents );
  1566.       }
  1567.       else {
  1568.      /* General case, convert image pixels into texels, scale, bias, etc */
  1569.      struct gl_texture_image *subTexImg = image_to_texture(ctx, image,
  1570.                     destTex->IntFormat, destTex->Border);
  1571.      GLubyte *dst = destTex->Data + texcomponents * xoffset;
  1572.      GLubyte *src = subTexImg->Data;
  1573.      MEMCPY( dst, src, width * texcomponents );
  1574.      gl_free_texture_image(subTexImg);
  1575.       }
  1576.  
  1577.       /* if the image's reference count is zero, delete it now */
  1578.       if (image->RefCount==0) {
  1579.      gl_free_image(image);
  1580.       }
  1581.  
  1582.       texSet->Current1D->Dirty = GL_TRUE;
  1583.       ctx->Texture.AnyDirty = GL_TRUE;
  1584.  
  1585.       /* tell driver about change */
  1586.       if (ctx->Driver.TexSubImage) {
  1587.     (*ctx->Driver.TexSubImage)( ctx, GL_TEXTURE_1D,
  1588.                     texSet->Current1D, level,
  1589.                     xoffset,0,width,1,
  1590.                     texSet->Current1D->Image[level]->IntFormat,
  1591.                     destTex );
  1592.       }
  1593.       else {
  1594.     if (ctx->Driver.TexImage) {
  1595.       (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D, texSet->Current1D, level,
  1596.                    texSet->Current1D->Image[level]->IntFormat,
  1597.                    destTex );
  1598.     }
  1599.       }
  1600.    }
  1601.    else {
  1602.       /* if no image, an error must have occured, do more testing now */
  1603.       GLint components, size;
  1604.  
  1605.       if (width<0) {
  1606.      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage1D(width)" );
  1607.      return;
  1608.       }
  1609.       if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1610.      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
  1611.      return;
  1612.       }
  1613.       components = components_in_intformat( format );
  1614.       if (components<0 || format==GL_STENCIL_INDEX
  1615.       || format==GL_DEPTH_COMPONENT){
  1616.      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
  1617.      return;
  1618.       }
  1619.       size = gl_sizeof_type( type );
  1620.       if (size<=0) {
  1621.      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(type)" );
  1622.      return;
  1623.       }
  1624.       /* if we get here, probably ran out of memory during unpacking */
  1625.       gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D" );
  1626.    }
  1627. }
  1628.  
  1629.  
  1630.  
  1631. void gl_TexSubImage2D( GLcontext *ctx,
  1632.                GLenum target, GLint level,
  1633.                GLint xoffset, GLint yoffset,
  1634.                GLsizei width, GLsizei height,
  1635.                GLenum format, GLenum type,
  1636.                struct gl_image *image )
  1637. {
  1638.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  1639.    struct gl_texture_image *destTex;
  1640.  
  1641.    if (target!=GL_TEXTURE_2D) {
  1642.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(target)" );
  1643.       return;
  1644.    }
  1645.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1646.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(level)" );
  1647.       return;
  1648.    }
  1649.  
  1650.    destTex = texSet->Current2D->Image[level];
  1651.    if (!destTex) {
  1652.       gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage2D" );
  1653.       return;
  1654.    }
  1655.  
  1656.    if (xoffset < -((GLint)destTex->Border)) {
  1657.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(xoffset)" );
  1658.       return;
  1659.    }
  1660.    if (yoffset < -((GLint)destTex->Border)) {
  1661.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(yoffset)" );
  1662.       return;
  1663.    }
  1664.    if (xoffset + width > (GLint) (destTex->Width + destTex->Border)) {
  1665.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(xoffset+width)" );
  1666.       return;
  1667.    }
  1668.    if (yoffset + height > (GLint) (destTex->Height + destTex->Border)) {
  1669.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(yoffset+height)" );
  1670.       return;
  1671.    }
  1672.  
  1673.    if (image) {
  1674.       /* unpacking must have been error-free */
  1675.       GLint texcomponents = components_in_intformat(destTex->Format);
  1676.  
  1677.       if (image->Type==GL_UNSIGNED_BYTE && texcomponents==image->Components) {
  1678.      /* Simple case, just byte copy image data into texture image */
  1679.      /* row by row. */
  1680.      GLubyte *dst = destTex->Data 
  1681.               + (yoffset * destTex->Width + xoffset) * texcomponents;
  1682.      GLubyte *src = (GLubyte *) image->Data;
  1683.      GLint  j;
  1684.      for (j=0;j<height;j++) {
  1685.         MEMCPY( dst, src, width * texcomponents );
  1686.         dst += destTex->Width * texcomponents * sizeof(GLubyte);
  1687.         src += width * texcomponents * sizeof(GLubyte);
  1688.      }
  1689.       }
  1690.       else {
  1691.      /* General case, convert image pixels into texels, scale, bias, etc */
  1692.      struct gl_texture_image *subTexImg = image_to_texture(ctx, image,
  1693.                     destTex->IntFormat, destTex->Border);
  1694.      GLubyte *dst = destTex->Data
  1695.           + (yoffset * destTex->Width + xoffset) * texcomponents;
  1696.      GLubyte *src = subTexImg->Data;
  1697.      GLint j;
  1698.      for (j=0;j<height;j++) {
  1699.         MEMCPY( dst, src, width * texcomponents );
  1700.         dst += destTex->Width * texcomponents * sizeof(GLubyte);
  1701.         src += width * texcomponents * sizeof(GLubyte);
  1702.      }
  1703.      gl_free_texture_image(subTexImg);
  1704.       }
  1705.  
  1706.       /* if the image's reference count is zero, delete it now */
  1707.       if (image->RefCount==0) {
  1708.      gl_free_image(image);
  1709.       }
  1710.  
  1711.       texSet->Current2D->Dirty = GL_TRUE;
  1712.       ctx->Texture.AnyDirty = GL_TRUE;
  1713.  
  1714.       /* tell driver about change */
  1715.       if (ctx->Driver.TexSubImage) {
  1716.     (*ctx->Driver.TexSubImage)( ctx, GL_TEXTURE_2D, texSet->Current2D, level,
  1717.                     xoffset, yoffset, width, height,
  1718.                     texSet->Current2D->Image[level]->IntFormat,
  1719.                     destTex );
  1720.       }
  1721.       else {
  1722.     if (ctx->Driver.TexImage) {
  1723.       (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D, texSet->Current2D, level,
  1724.                    texSet->Current2D->Image[level]->IntFormat,
  1725.                    destTex );
  1726.     }
  1727.       }
  1728.    }
  1729.    else {
  1730.       /* if no image, an error must have occured, do more testing now */
  1731.       GLint components, size;
  1732.  
  1733.       if (width<0) {
  1734.      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(width)" );
  1735.      return;
  1736.       }
  1737.       if (height<0) {
  1738.      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage2D(height)" );
  1739.      return;
  1740.       }
  1741.       if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1742.      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage1D(format)" );
  1743.      return;
  1744.       }
  1745.       components = gl_components_in_format( format );
  1746.       if (components<0 || format==GL_STENCIL_INDEX
  1747.       || format==GL_DEPTH_COMPONENT){
  1748.      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(format)" );
  1749.      return;
  1750.       }
  1751.       size = gl_sizeof_type( type );
  1752.       if (size<=0) {
  1753.      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage2D(type)" );
  1754.      return;
  1755.       }
  1756.       /* if we get here, probably ran out of memory during unpacking */
  1757.       gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D" );
  1758.    }
  1759. }
  1760.  
  1761.  
  1762.  
  1763. void gl_TexSubImage3DEXT( GLcontext *ctx,
  1764.               GLenum target, GLint level,
  1765.               GLint xoffset, GLint yoffset, GLint zoffset,
  1766.               GLsizei width, GLsizei height, GLsizei depth,
  1767.               GLenum format, GLenum type,
  1768.               struct gl_image *image )
  1769. {
  1770.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  1771.    struct gl_texture_image *destTex;
  1772.  
  1773.    if (target!=GL_TEXTURE_3D_EXT) {
  1774.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(target)" );
  1775.       return;
  1776.    }
  1777.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  1778.       gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(level)" );
  1779.       return;
  1780.    }
  1781.  
  1782.    destTex = texSet->Current3D->Image[level];
  1783.    if (!destTex) {
  1784.       gl_error( ctx, GL_INVALID_OPERATION, "glTexSubImage3DEXT" );
  1785.       return;
  1786.    }
  1787.  
  1788.    if (xoffset < -((GLint)destTex->Border)) {
  1789.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(xoffset)" );
  1790.       return;
  1791.    }
  1792.    if (yoffset < -((GLint)destTex->Border)) {
  1793.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(yoffset)" );
  1794.       return;
  1795.    }
  1796.    if (zoffset < -((GLint)destTex->Border)) {
  1797.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(zoffset)" );
  1798.       return;
  1799.    }
  1800.    if (xoffset + width > (GLint) (destTex->Width+destTex->Border)) {
  1801.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(xoffset+width)" );
  1802.       return;
  1803.    }
  1804.    if (yoffset + height > (GLint) (destTex->Height+destTex->Border)) {
  1805.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(yoffset+height)" );
  1806.       return;
  1807.    }
  1808.    if (zoffset + depth  > (GLint) (destTex->Depth+destTex->Border)) {
  1809.       gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(zoffset+depth)" );
  1810.       return;
  1811.    }
  1812.  
  1813.    if (image) {
  1814.       /* unpacking must have been error-free */
  1815.       GLint texcomponents = components_in_intformat(destTex->Format);
  1816.       GLint dstRectArea = destTex->Width * destTex->Height;
  1817.       GLint srcRectArea = width * height;
  1818.  
  1819.       if (image->Type==GL_UNSIGNED_BYTE && texcomponents==image->Components) {
  1820.      /* Simple case, just byte copy image data into texture image */
  1821.      /* row by row. */
  1822.      GLubyte *dst = destTex->Data 
  1823.            + (zoffset * dstRectArea +  yoffset * destTex->Width + xoffset)
  1824.            * texcomponents;
  1825.      GLubyte *src = (GLubyte *) image->Data;
  1826.      GLint j, k;
  1827.      for(k=0;k<depth; k++) {
  1828.        for (j=0;j<height;j++) {
  1829.           MEMCPY( dst, src, width * texcomponents );
  1830.           dst += destTex->Width * texcomponents;
  1831.           src += width * texcomponents;
  1832.        }
  1833.        dst += dstRectArea * texcomponents * sizeof(GLubyte);
  1834.        src += srcRectArea * texcomponents * sizeof(GLubyte);
  1835.      }
  1836.       }
  1837.       else {
  1838.      /* General case, convert image pixels into texels, scale, bias, etc */
  1839.      struct gl_texture_image *subTexImg = image_to_texture(ctx, image,
  1840.                     destTex->IntFormat, destTex->Border);
  1841.      GLubyte *dst = destTex->Data 
  1842.            + (zoffset * dstRectArea +  yoffset * destTex->Width + xoffset)
  1843.            * texcomponents;
  1844.      GLubyte *src = subTexImg->Data;
  1845.      GLint j, k;
  1846.      for(k=0;k<depth; k++) {
  1847.        for (j=0;j<height;j++) {
  1848.           MEMCPY( dst, src, width * texcomponents );
  1849.           dst += destTex->Width * texcomponents;
  1850.           src += width * texcomponents;
  1851.        }
  1852.        dst += dstRectArea * texcomponents * sizeof(GLubyte);
  1853.        src += srcRectArea * texcomponents * sizeof(GLubyte);
  1854.      }
  1855.      gl_free_texture_image(subTexImg);
  1856.       }
  1857.       /* if the image's reference count is zero, delete it now */
  1858.       if (image->RefCount==0) {
  1859.      gl_free_image(image);
  1860.       }
  1861.  
  1862.       texSet->Current3D->Dirty = GL_TRUE;
  1863.       ctx->Texture.AnyDirty = GL_TRUE;
  1864.  
  1865.       /* tell driver about change */
  1866.       if (ctx->Driver.TexImage) {
  1867.      (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT, texSet->Current3D,
  1868.                   level, texSet->Current3D->Image[level]->IntFormat,
  1869.                   destTex );
  1870.       }
  1871.    }
  1872.    else {
  1873.       /* if no image, an error must have occured, do more testing now */
  1874.       GLint components, size;
  1875.  
  1876.       if (width<0) {
  1877.      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(width)" );
  1878.      return;
  1879.       }
  1880.       if (height<0) {
  1881.      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(height)" );
  1882.      return;
  1883.       }
  1884.       if (depth<0) {
  1885.      gl_error( ctx, GL_INVALID_VALUE, "glTexSubImage3DEXT(depth)" );
  1886.      return;
  1887.       }
  1888.       if (type==GL_BITMAP && format!=GL_COLOR_INDEX) {
  1889.      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(format)" );
  1890.      return;
  1891.       }
  1892.       components = components_in_intformat( format );
  1893.       if (components<0 || format==GL_STENCIL_INDEX
  1894.       || format==GL_DEPTH_COMPONENT){
  1895.      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(format)" );
  1896.      return;
  1897.       }
  1898.       size = gl_sizeof_type( type );
  1899.       if (size<=0) {
  1900.      gl_error( ctx, GL_INVALID_ENUM, "glTexSubImage3DEXT(type)" );
  1901.      return;
  1902.       }
  1903.       /* if we get here, probably ran out of memory during unpacking */
  1904.       gl_error( ctx, GL_OUT_OF_MEMORY, "glTexSubImage3DEXT" );
  1905.    }
  1906. }
  1907.  
  1908.  
  1909.  
  1910. /*
  1911.  * Read an RGBA image from the frame buffer.
  1912.  * Input:  ctx - the context
  1913.  *         x, y - lower left corner
  1914.  *         width, height - size of region to read
  1915.  *         format - one of GL_RED, GL_RGB, GL_LUMINANCE, etc.
  1916.  * Return: gl_image pointer or NULL if out of memory
  1917.  */
  1918. static struct gl_image *read_color_image( GLcontext *ctx, GLint x, GLint y,
  1919.                       GLsizei width, GLsizei height,
  1920.                       GLenum format )
  1921. {
  1922.    struct gl_image *image;
  1923.    GLubyte *imgptr;
  1924.    GLint components;
  1925.    GLint i, j;
  1926.  
  1927.    components = components_in_intformat( format );
  1928.  
  1929.    /*
  1930.     * Allocate image struct and image data buffer
  1931.     */
  1932.    image = (struct gl_image *) malloc( sizeof(struct gl_image) );
  1933.    if (image) {
  1934.       image->Width = width;
  1935.       image->Height = height;
  1936.       image->Depth = 1;
  1937.       image->Components = components;
  1938.       image->Format = format;
  1939.       image->Type = GL_UNSIGNED_BYTE;
  1940.       image->RefCount = 0;
  1941.       image->Data = (GLubyte *) malloc( width * height * components );
  1942.       if (!image->Data) {
  1943.      free(image);
  1944.      return NULL;
  1945.       }
  1946.    }
  1947.    else {
  1948.       return NULL;
  1949.    }
  1950.  
  1951.    imgptr = (GLubyte *) image->Data;
  1952.  
  1953.    /* Select buffer to read from */
  1954.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.ReadBuffer );
  1955.  
  1956.    for (j=0;j<height;j++) {
  1957.       GLubyte rgba[MAX_WIDTH][4];
  1958.       gl_read_rgba_span( ctx, width, x, y+j, rgba );
  1959.  
  1960.       switch (format) {
  1961.      case GL_ALPHA:
  1962.         for (i=0;i<width;i++) {
  1963.            *imgptr++ = rgba[i][ACOMP];
  1964.         }
  1965.         break;
  1966.      case GL_LUMINANCE:
  1967.         for (i=0;i<width;i++) {
  1968.            *imgptr++ = rgba[i][RCOMP];
  1969.         }
  1970.         break;
  1971.      case GL_LUMINANCE_ALPHA:
  1972.         for (i=0;i<width;i++) {
  1973.            *imgptr++ = rgba[i][RCOMP];
  1974.            *imgptr++ = rgba[i][ACOMP];
  1975.         }
  1976.         break;
  1977.      case GL_INTENSITY:
  1978.         for (i=0;i<width;i++) {
  1979.            *imgptr++ = rgba[i][RCOMP];
  1980.         }
  1981.         break;
  1982.      case GL_RGB:
  1983.         for (i=0;i<width;i++) {
  1984.            *imgptr++ = rgba[i][RCOMP];
  1985.            *imgptr++ = rgba[i][GCOMP];
  1986.            *imgptr++ = rgba[i][BCOMP];
  1987.         }
  1988.         break;
  1989.      case GL_RGBA:
  1990.         for (i=0;i<width;i++) {
  1991.            *imgptr++ = rgba[i][RCOMP];
  1992.            *imgptr++ = rgba[i][GCOMP];
  1993.            *imgptr++ = rgba[i][BCOMP];
  1994.            *imgptr++ = rgba[i][ACOMP];
  1995.         }
  1996.         break;
  1997.      default:
  1998.         gl_problem(ctx, "Bad format in read_color_image");
  1999.         break;
  2000.       } /*switch*/
  2001.  
  2002.    } /*for*/         
  2003.  
  2004.    /* Restore drawing buffer */
  2005.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer );
  2006.  
  2007.    return image;
  2008. }
  2009.  
  2010.  
  2011.  
  2012.  
  2013. void gl_CopyTexImage1D( GLcontext *ctx,
  2014.             GLenum target, GLint level,
  2015.             GLenum internalformat,
  2016.             GLint x, GLint y,
  2017.             GLsizei width, GLint border )
  2018. {
  2019.    GLint format;
  2020.    struct gl_image *teximage;
  2021.  
  2022.    if (INSIDE_BEGIN_END(ctx)) {
  2023.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexImage1D" );
  2024.       return;
  2025.    }
  2026.    if (target!=GL_TEXTURE_1D) {
  2027.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexImage1D(target)" );
  2028.       return;
  2029.    }
  2030.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2031.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(level)" );
  2032.       return;
  2033.    }
  2034.    if (border!=0 && border!=1) {
  2035.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(border)" );
  2036.       return;
  2037.    }
  2038.    if (width<2*border || width>2+MAX_TEXTURE_SIZE || width<0) {
  2039.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(width)" );
  2040.       return;
  2041.    }
  2042.    format = decode_internal_format( internalformat );
  2043.    if (format<0 || (internalformat>=1 && internalformat<=4)) {
  2044.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage1D(format)" );
  2045.       return;
  2046.    }
  2047.  
  2048.    teximage = read_color_image( ctx, x, y, width, 1, (GLenum) format );
  2049.    if (!teximage) {
  2050.       gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D" );
  2051.       return;
  2052.    }
  2053.  
  2054.    gl_TexImage1D( ctx, target, level, internalformat, width,
  2055.           border, GL_RGBA, GL_UNSIGNED_BYTE, teximage );
  2056.  
  2057.    /* teximage was freed in gl_TexImage1D */
  2058. }
  2059.  
  2060.  
  2061.  
  2062. void gl_CopyTexImage2D( GLcontext *ctx,
  2063.             GLenum target, GLint level, GLenum internalformat,
  2064.             GLint x, GLint y, GLsizei width, GLsizei height,
  2065.             GLint border )
  2066. {
  2067.    GLint format;
  2068.    struct gl_image *teximage;
  2069.  
  2070.    if (INSIDE_BEGIN_END(ctx)) {
  2071.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexImage2D" );
  2072.       return;
  2073.    }
  2074.    if (target!=GL_TEXTURE_2D) {
  2075.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexImage2D(target)" );
  2076.       return;
  2077.    }
  2078.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2079.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(level)" );
  2080.       return;
  2081.    }
  2082.    if (border!=0 && border!=1) {
  2083.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(border)" );
  2084.       return;
  2085.    }
  2086.    if (width<2*border || width>2+MAX_TEXTURE_SIZE || width<0) {
  2087.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(width)" );
  2088.       return;
  2089.    }
  2090.    if (height<2*border || height>2+MAX_TEXTURE_SIZE || height<0) {
  2091.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(height)" );
  2092.       return;
  2093.    }
  2094.    format = decode_internal_format( internalformat );
  2095.    if (format<0 || (internalformat>=1 && internalformat<=4)) {
  2096.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexImage2D(format)" );
  2097.       return;
  2098.    }
  2099.  
  2100.    teximage = read_color_image( ctx, x, y, width, height, (GLenum) format );
  2101.    if (!teximage) {
  2102.       gl_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D" );
  2103.       return;
  2104.    }
  2105.  
  2106.    gl_TexImage2D( ctx, target, level, internalformat, width, height,
  2107.           border, GL_RGBA, GL_UNSIGNED_BYTE, teximage );
  2108.  
  2109.    /* teximage was freed in gl_TexImage2D */
  2110. }
  2111.  
  2112.  
  2113.  
  2114.  
  2115. /*
  2116.  * Do the work of glCopyTexSubImage[123]D.
  2117.  * TODO: apply pixel bias scale and mapping.
  2118.  */
  2119. static void copy_tex_sub_image( GLcontext *ctx, struct gl_texture_image *dest,
  2120.                 GLint width, GLint height,
  2121.                 GLint srcx, GLint srcy,
  2122.                 GLint dstx, GLint dsty, GLint zoffset )
  2123. {
  2124.    GLint i, j;
  2125.    GLint format, components, rectarea;
  2126.    GLint texwidth, texheight; 
  2127.  
  2128.    texwidth = dest->Width;
  2129.    texheight = dest->Height;
  2130.    rectarea = texwidth * texheight;
  2131.    zoffset *= rectarea; 
  2132.    format = dest->Format;
  2133.    components = components_in_intformat( format );
  2134.  
  2135.    /* Select buffer to read from */
  2136.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Pixel.ReadBuffer );
  2137.  
  2138.    for (j=0;j<height;j++) {
  2139.       GLubyte rgba[MAX_WIDTH][4];
  2140.       GLubyte *texptr;
  2141.  
  2142.       gl_read_rgba_span( ctx, width, srcx, srcy+j, rgba );
  2143.  
  2144.       texptr = dest->Data + ( zoffset + (dsty+j) * texwidth + dstx) * components;
  2145.  
  2146.       switch (format) {
  2147.      case GL_ALPHA:
  2148.         for (i=0;i<width;i++) {
  2149.            *texptr++ = rgba[i][ACOMP];
  2150.         }
  2151.         break;
  2152.      case GL_LUMINANCE:
  2153.         for (i=0;i<width;i++) {
  2154.            *texptr++ = rgba[i][RCOMP];
  2155.         }
  2156.         break;
  2157.      case GL_LUMINANCE_ALPHA:
  2158.         for (i=0;i<width;i++) {
  2159.            *texptr++ = rgba[i][RCOMP];
  2160.            *texptr++ = rgba[i][ACOMP];
  2161.         }
  2162.         break;
  2163.      case GL_INTENSITY:
  2164.         for (i=0;i<width;i++) {
  2165.            *texptr++ = rgba[i][RCOMP];
  2166.         }
  2167.         break;
  2168.      case GL_RGB:
  2169.         for (i=0;i<width;i++) {
  2170.            *texptr++ = rgba[i][RCOMP];
  2171.            *texptr++ = rgba[i][GCOMP];
  2172.            *texptr++ = rgba[i][BCOMP];
  2173.         }
  2174.         break;
  2175.      case GL_RGBA:
  2176.         for (i=0;i<width;i++) {
  2177.            *texptr++ = rgba[i][RCOMP];
  2178.            *texptr++ = rgba[i][GCOMP];
  2179.            *texptr++ = rgba[i][BCOMP];
  2180.            *texptr++ = rgba[i][ACOMP];
  2181.         }
  2182.         break;
  2183.       } /*switch*/
  2184.    } /*for*/         
  2185.  
  2186.  
  2187.    /* Restore drawing buffer */
  2188.    (void) (*ctx->Driver.SetBuffer)( ctx, ctx->Color.DrawBuffer );
  2189. }
  2190.  
  2191.  
  2192.  
  2193.  
  2194. void gl_CopyTexSubImage1D( GLcontext *ctx,
  2195.                   GLenum target, GLint level,
  2196.                   GLint xoffset, GLint x, GLint y, GLsizei width )
  2197. {
  2198.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  2199.    struct gl_texture_image *teximage;
  2200.  
  2201.    if (INSIDE_BEGIN_END(ctx)) {
  2202.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage1D" );
  2203.       return;
  2204.    }
  2205.    if (target!=GL_TEXTURE_1D) {
  2206.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage1D(target)" );
  2207.       return;
  2208.    }
  2209.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2210.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(level)" );
  2211.       return;
  2212.    }
  2213.    if (width<0) {
  2214.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(width)" );
  2215.       return;
  2216.    }
  2217.  
  2218.    teximage = texSet->Current1D->Image[level];
  2219.  
  2220.    if (teximage) {
  2221.       if (xoffset < -((GLint)teximage->Border)) {
  2222.      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage1D(xoffset)" );
  2223.      return;
  2224.       }
  2225.       /* NOTE: we're adding the border here, not subtracting! */
  2226.       if (xoffset+width > (GLint) (teximage->Width+teximage->Border)) {
  2227.      gl_error( ctx, GL_INVALID_VALUE,
  2228.            "glCopyTexSubImage1D(xoffset+width)" );
  2229.      return;
  2230.       }
  2231.       if (teximage->Data) {
  2232.      copy_tex_sub_image( ctx, teximage, width, 1, x, y, xoffset, 0, 0 );
  2233.  
  2234.      /* tell driver about change */
  2235.      if (ctx->Driver.TexSubImage) {
  2236.        (*ctx->Driver.TexSubImage)( ctx, GL_TEXTURE_1D,
  2237.                        texSet->Current1D, level,
  2238.                        xoffset,0,width,1,
  2239.                        teximage->IntFormat,
  2240.                        teximage );
  2241.      }
  2242.      else {
  2243.        if (ctx->Driver.TexImage) {
  2244.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_1D, texSet->Current1D, level,
  2245.                       teximage->IntFormat,
  2246.                       teximage );
  2247.        }
  2248.      }
  2249.       }
  2250.    }
  2251.    else {
  2252.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage1D" );
  2253.    }
  2254. }
  2255.  
  2256.  
  2257.  
  2258. void gl_CopyTexSubImage2D( GLcontext *ctx,
  2259.                   GLenum target, GLint level,
  2260.                   GLint xoffset, GLint yoffset,
  2261.                   GLint x, GLint y, GLsizei width, GLsizei height )
  2262. {
  2263.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  2264.    struct gl_texture_image *teximage;
  2265.  
  2266.    if (INSIDE_BEGIN_END(ctx)) {
  2267.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D" );
  2268.       return;
  2269.    }
  2270.    if (target!=GL_TEXTURE_2D) {
  2271.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage2D(target)" );
  2272.       return;
  2273.    }
  2274.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2275.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(level)" );
  2276.       return;
  2277.    }
  2278.    if (width<0) {
  2279.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(width)" );
  2280.       return;
  2281.    }
  2282.    if (height<0) {
  2283.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(height)" );
  2284.       return;
  2285.    }
  2286.  
  2287.    teximage = texSet->Current2D->Image[level];
  2288.  
  2289.    if (teximage) {
  2290.       if (xoffset < -((GLint)teximage->Border)) {
  2291.      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(xoffset)" );
  2292.      return;
  2293.       }
  2294.       if (yoffset < -((GLint)teximage->Border)) {
  2295.      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage2D(yoffset)" );
  2296.      return;
  2297.       }
  2298.       /* NOTE: we're adding the border here, not subtracting! */
  2299.       if (xoffset+width > (GLint) (teximage->Width+teximage->Border)) {
  2300.      gl_error( ctx, GL_INVALID_VALUE,
  2301.            "glCopyTexSubImage2D(xoffset+width)" );
  2302.      return;
  2303.       }
  2304.       if (yoffset+height > (GLint) (teximage->Height+teximage->Border)) {
  2305.      gl_error( ctx, GL_INVALID_VALUE,
  2306.            "glCopyTexSubImage2D(yoffset+height)" );
  2307.      return;
  2308.       }
  2309.  
  2310.       if (teximage->Data) {
  2311.      copy_tex_sub_image( ctx, teximage, width, height,
  2312.                  x, y, xoffset, yoffset, 0 );
  2313.      /* tell driver about change */
  2314.      if (ctx->Driver.TexSubImage) {
  2315.        (*ctx->Driver.TexSubImage)( ctx, GL_TEXTURE_2D, texSet->Current2D, level,
  2316.                        xoffset, yoffset, width, height,
  2317.                        teximage->IntFormat,
  2318.                        teximage );
  2319.      }
  2320.      else {
  2321.        if (ctx->Driver.TexImage) {
  2322.          (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_2D, texSet->Current2D, level,
  2323.                       teximage->IntFormat,
  2324.                       teximage );
  2325.        }
  2326.      }
  2327.       }
  2328.    }
  2329.    else {
  2330.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage2D" );
  2331.    }
  2332. }
  2333.  
  2334.  
  2335.  
  2336. void gl_CopyTexSubImage3DEXT( GLcontext *ctx,
  2337.                   GLenum target, GLint level,
  2338.                   GLint xoffset, GLint yoffset, GLint zoffset,
  2339.                   GLint x, GLint y, GLsizei width, GLsizei height )
  2340. {
  2341.    struct gl_texture_set *texSet = &ctx->Texture.Set[ctx->Texture.CurrentSet];
  2342.    struct gl_texture_image *teximage;
  2343.  
  2344.    if (INSIDE_BEGIN_END(ctx)) {
  2345.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage3DEXT" );
  2346.       return;
  2347.    }
  2348.    if (target!=GL_TEXTURE_2D) {
  2349.       gl_error( ctx, GL_INVALID_ENUM, "glCopyTexSubImage3DEXT(target)" );
  2350.       return;
  2351.    }
  2352.    if (level<0 || level>=MAX_TEXTURE_LEVELS) {
  2353.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(level)" );
  2354.       return;
  2355.    }
  2356.    if (width<0) {
  2357.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(width)" );
  2358.       return;
  2359.    }
  2360.    if (height<0) {
  2361.       gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(height)" );
  2362.       return;
  2363.    }
  2364.  
  2365.    teximage = texSet->Current3D->Image[level];
  2366.    if (teximage) {
  2367.       if (xoffset < -((GLint)teximage->Border)) {
  2368.      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(xoffset)" );
  2369.      return;
  2370.       }
  2371.       if (yoffset < -((GLint)teximage->Border)) {
  2372.      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(yoffset)" );
  2373.      return;
  2374.       }
  2375.       if (zoffset < -((GLint)teximage->Border)) {
  2376.      gl_error( ctx, GL_INVALID_VALUE, "glCopyTexSubImage3DEXT(zoffset)" );
  2377.      return;
  2378.       }
  2379.       /* NOTE: we're adding the border here, not subtracting! */
  2380.       if (xoffset+width > (GLint) (teximage->Width+teximage->Border)) {
  2381.      gl_error( ctx, GL_INVALID_VALUE,
  2382.            "glCopyTexSubImage3DEXT(xoffset+width)" );
  2383.      return;
  2384.       }
  2385.       if (yoffset+height > (GLint) (teximage->Height+teximage->Border)) {
  2386.      gl_error( ctx, GL_INVALID_VALUE,
  2387.            "glCopyTexSubImage3DEXT(yoffset+height)" );
  2388.      return;
  2389.       }
  2390.       if (zoffset > (GLint) (teximage->Depth+teximage->Border)) {
  2391.      gl_error( ctx, GL_INVALID_VALUE,
  2392.            "glCopyTexSubImage3DEXT(zoffset+depth)" );
  2393.      return;
  2394.       }
  2395.  
  2396.       if (teximage->Data) {
  2397.      copy_tex_sub_image( ctx, teximage, width, height, 
  2398.                  x, y, xoffset, yoffset, zoffset);
  2399.  
  2400.      /* tell driver about change */
  2401.      if (ctx->Driver.TexImage) {
  2402.        (*ctx->Driver.TexImage)( ctx, GL_TEXTURE_3D_EXT, texSet->Current3D,
  2403.                     level, teximage->IntFormat,
  2404.                     teximage );
  2405.      }
  2406.       }
  2407.    }
  2408.    else {
  2409.       gl_error( ctx, GL_INVALID_OPERATION, "glCopyTexSubImage3DEXT" );
  2410.    }
  2411. }
  2412.  
  2413.